package org.rainbowinverted.charging.device.connect.ykc.server.handler;

import org.rainbowinverted.charging.device.connect.ykc.server.constants.YkcDeviceStopChargeErrorReasonEnum;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcDeviceStopChargeIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcMessageIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.out.YkcDeviceStopChargeOut;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 停止充电处理器
 * @author hehuaiping
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class YkcDeviceStopChargeHandler extends YkcAbstractHandler<YkcDeviceStopChargeIn, YkcDeviceStopChargeOut> {

    @Override
    public void read(ChannelHandlerContext channel, YkcMessageIn message) {
        ByteBuf messageBody = message.getMessageBody();
        Long deviceNo = readDeviceNo(messageBody);
        Integer gunNo = readGunNo(messageBody);
        Boolean controlSuccessful = messageBody.readByte() == 0x01;
        YkcDeviceStopChargeErrorReasonEnum stopChargeErrorReasonEnum = parseErrorReason(messageBody.readByte());
        YkcDeviceStopChargeIn stopChargeIn = YkcDeviceStopChargeIn.of(deviceNo, gunNo, controlSuccessful, stopChargeErrorReasonEnum);
        complete(message.getFrameSerialNo(), stopChargeIn);
        log.info("device stop charge info: {}", stopChargeIn);
    }

    @Override
    public void write(ByteBuf byteBuf, YkcDeviceStopChargeOut ykcDeviceStopChargeOut) {
        writeDeviceNo(byteBuf, ykcDeviceStopChargeOut.getDeviceNo());
        writeGunNo(byteBuf, ykcDeviceStopChargeOut.getGunNo());
        createCompletableFuture(ykcDeviceStopChargeOut.getFrameSerialNo());
    }

    private YkcDeviceStopChargeErrorReasonEnum parseErrorReason(Byte errorReasonByte) {
        return switch (errorReasonByte) {
            case 0x00 -> YkcDeviceStopChargeErrorReasonEnum.NONE;
            case 0x01 -> YkcDeviceStopChargeErrorReasonEnum.DEVICE_NO_NOT_MATCH;
            case 0x02 -> YkcDeviceStopChargeErrorReasonEnum.NOT_CHARGING;
            default -> YkcDeviceStopChargeErrorReasonEnum.OTHER;
        };
    }
}
